﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CharacterTrailClient.Binding;
using CharacterTrailClient.Message;
using CharacterTrailLibrary.Factory;
using CharacterTrailLibrary.Interface;
using CharacterTrailLibrary.Persist.BLL.Model;
using CharacterTrailLibrary.Security;
using DevExpress.XtraEditors;
using Telegnosis.Framework.Constants;

namespace CharacterTrailClient.Controls
{
    public partial class ProductHeaderAndDetailEdit : XtraUserControl
    {
        private const int RowHeight = 24;
        private readonly List<TBomEntryModel> _bomEntryModels = new List<TBomEntryModel>();
        private readonly List<BomEntrySingleModel> _bomEntrySingleModels = new List<BomEntrySingleModel>();
        private readonly IBom _bomImpl;
        private readonly IProductPersist _productPersist;
        private readonly IStaticDataQuerier _staticDataQuerier;
        private readonly List<BarCodeAndNameWrap> _wrapList = new List<BarCodeAndNameWrap>();
        private ProductBaseEdit _parentProductBaseEdit;
        private TProductHeaderModel _productHeaderModel;

        public ProductHeaderAndDetailEdit()
        {
            _productPersist = InstanceFactory.GetProductPersist();
            //_bomHeaderPersist = InstanceFactory.GetBomHeaderPersis();
            _bomImpl = InstanceFactory.GetBom();
            _staticDataQuerier = InstanceFactory.GetStaticDataQuerier();
            InitializeComponent();
            barCodeAndNameParent.TextBoxInputBarCodeValidatedEnd +=
                (barCodeAndName, printlogModel) => AddProductHeader(barCodeAndName.BarCode, printlogModel);
            if (GlobalClass.RunTimeMode)
            {
                DataBinder.BindingProcedure(lookUpEditProcedureNo, textEditProcedureName);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (GlobalClass.RunTimeMode)
            {
                _parentProductBaseEdit = (ProductBaseEdit) Parent;
            }
        }

        public void SetFocus()
        {
            textEditOrderId.Focus();
        }

        private void ClearPanel()
        {
            foreach (var productHeaderAndDetailEditWrap in _wrapList)
            {
                if (groupControlMain.Controls.Contains(productHeaderAndDetailEditWrap.BarCodeAndNameObject))
                {
                    productHeaderAndDetailEditWrap.BarCodeAndNameObject.TextBoxInputBarCodeValidatedEnd -= BarCodeAndNameObject_BarCodeInputEnd;
                    groupControlMain.Controls.Remove(productHeaderAndDetailEditWrap.BarCodeAndNameObject);
                    productHeaderAndDetailEditWrap.Dispose();
                }
            }
            _wrapList.Clear();
        }

        public void InitializeInputProduct()
        {
            ClearPanel();
            barCodeAndNameParent.BarCode = "";
            barCodeAndNameParent.FName = "";
        }

        /// <summary>
        ///   给产品barcode赋值，注意，调用此方法是已经从数据库中找到了条码对象
        /// </summary>
        /// <param name = "parentBarCode"></param>
        /// <param name = "printlogModel"></param>
        public void AddProductHeader(string parentBarCode, lmbcprintlogModel printlogModel)
        {
            var procedureNo = lookUpEditProcedureNo.Text.Trim();
            if (String.IsNullOrEmpty(textEditOrderId.Text.Trim()) || string.IsNullOrEmpty(procedureNo))
            {
                MsgBox.ShowError("请先填入订单号和工序，再扫描条码！");
                barCodeAndNameParent.ResetBarCode();
                barCodeAndNameParent.Focus();
                return;
            }


            ClearPanel();
            //add controls to this panel .......
            _productHeaderModel = _productPersist.GetProductHeaderModel(parentBarCode, lookUpEditProcedureNo.Text.Trim());
            if (_productHeaderModel == null)
            {
                _productHeaderModel = new TProductHeaderModel();
                _productHeaderModel.EditFlag = Enums.EditFlag.New;
                _productHeaderModel.InputDate = DateTime.Now;
                _productHeaderModel.InputId = UserSession.CurrentUser.UserId;
                _productHeaderModel.ExtChar4 = UserSession.CurrentUser.UserName;
                //var imbcprintlog = _staticDataQuerier.GetlmbcprintlogModel(parentBarCode);
                var imbcprintlog = printlogModel;
                //if(imbcprintlog == null)
                //{
                //    Message.MsgBox.ShowError(String.Format("条码不在系统中：{0}",parentBarCode));
                //    return;
                //}
                //查物料表，看是否物料在系统中
                var iCItemModel = _staticDataQuerier.GetVIcItemQueryModel(imbcprintlog.Fitemid);
                if (iCItemModel == null)
                {
                    MsgBox.ShowError(String.Format("产品/物料不在系统中：{0}", imbcprintlog.Fitemid));
                    return;
                }

                barCodeAndNameParent.FName = iCItemModel.FName;

                _productHeaderModel.ProductItemBarCode = barCodeAndNameParent.BarCode;
                _productHeaderModel.OrderId = textEditOrderId.Text.Trim();
                _productHeaderModel.ProcedureNo = procedureNo;
                _productHeaderModel.ProcedureName = textEditProcedureName.Text.Trim();

                //三个属性都必须加上
                _productHeaderModel.ProductItemId = imbcprintlog.Fitemid;
                _productHeaderModel.ProductItemName = iCItemModel.FName;
                _productHeaderModel.ProductItemNumber = iCItemModel.FNumber;

                barCodeAndNameParent.FProductHeaderModel = _productHeaderModel;
            }
            else
            {
                MsgBox.ShowError(String.Format("产品{0}的工序{1}条码{2}已经录入！", _productHeaderModel.ProductItemName, procedureNo,
                                               printlogModel.Fbarcode));
                barCodeAndNameParent.ResetBarCode();
                barCodeAndNameParent.Focus();
                return;
            }
            //查询Bom，根据ParentItemID查询出所有的
            //var childBoms = _bomHeaderPersist.GetTBomHeaderModels(String.Format(" ParentItemId = {0}", _productHeaderModel.ProductItemId));

            var bomMainModels =
                _bomImpl.GetBomMainModelsByCondition(String.Format(" ProductItemId = {0} and CheckStatus = 1",
                                                                   _productHeaderModel.ProductItemId));

            if (bomMainModels.Count == 0)
            {
                MsgBox.ShowError(String.Format("Bom中没有该产品审核过的记录：{0}", _productHeaderModel.ProductItemName));
                return;
            }
            else if (bomMainModels.Count > 1)
            {
                MsgBox.ShowError(String.Format("Bom中存在超过1条的该产品审核过的记录：{0}", _productHeaderModel.ProductItemName));
                return;
            }
            var bomMainModel = bomMainModels[0];
            var bomEntryModels = _bomImpl.GetBomEntryModelsByProduct(bomMainModel.ProductItemId,
                                                                     bomMainModel.ProductVersion, procedureNo);

            //清除掉
            _bomEntryModels.Clear();
            //重新加入最新的
            foreach (var bomEntryModel in bomEntryModels)
            {
                _bomEntryModels.Add(bomEntryModel);
            }

            _bomEntrySingleModels.Clear();
            foreach (var bomEntryModel in bomEntryModels)
            {
                var quantity = (int) bomEntryModel.Qty;

                for (var idx = 1; idx <= quantity; idx++)
                {
                    var obj = new BomEntrySingleModel {FBomEntryModel = bomEntryModel, IsAddToTheControl = false};
                    _bomEntrySingleModels.Add(obj);
                }
            }

            BarCodeAndNameWrap orignalWrap = null;
            var x = barCodeAndNameParent.Left;
            var y = barCodeAndNameParent.Top + barCodeAndNameParent.Height + 3;
            var index = 1;

            foreach (var entryModel in _bomEntryModels)
            {
                var quantity = (int) entryModel.Qty;

                for (var idx = 1; idx <= quantity; idx++)
                {
                    var wrap = new BarCodeAndNameWrap(groupControlMain)
                                   {
                                       PositionX = x,
                                       PositionY = y,
                                       Index = index,
                                       BarCodeAndNameObject = {IsParentProduct = false} //,
                                       //FBomMainModel = bomMainModel
                                   };
                    wrap.BarCodeAndNameObject.LabelText = "物料条码";
                    //wrap.FBomEntryModel = entryModel;

                    wrap.BarCodeAndNameObject.TextBoxInputBarCodeValidatedEnd += BarCodeAndNameObject_BarCodeInputEnd;

                    _wrapList.Add(wrap);
                    if (orignalWrap != null)
                    {
                        orignalWrap.NextBarCodeAndNameWrapObject = wrap;
                    }
                    orignalWrap = wrap;
                    y += RowHeight;
                    index++;
                    wrap.DrawBarCodeAndName();
                }
            }

            #region 暂时作废

            //foreach (var bom in childBoms)
            //{
            //    var quantity = (int)bom.Qty;
            //    for (int idx = 1; idx <= quantity; idx++)
            //    {
            //        var wrap = new BarCodeAndNameWrap(this.groupControlMain) {PositionX = x, PositionY = y, Index = index};
            //        wrap.ChildItemName = bom.ChildItemName;
            //        wrap.BarCodeAndNameObject.IsParentProduct = false;
            //        //wrap.FBomMainModel
            //        //wrap.FBomHeaderModel = bom;
            //        //wrap.BarCodeAndNameObject.LabelText = String.Format("物料{0}条码",index);
            //        wrap.BarCodeAndNameObject.TextBoxInputBarCodeValidatedEnd += new BarCodeAndName.TextBoxInputBarCodeValidatedEndEventHandler(BarCodeAndNameObject_BarCodeInputEnd);
            //        WrapList.Add(wrap);
            //        if (orignalWrap != null)
            //        {
            //           orignalWrap.NextBarCodeAndNameWrapObject = wrap;
            //        }
            //        orignalWrap = wrap;
            //        y += RowHeight;
            //        index++;
            //        wrap.DrawBarCodeAndName();
            //    }
            //}

            #endregion

            if (orignalWrap != null)
                orignalWrap.IsTheLastControl = true;

            SetFocus(0);
        }

        private BarCodeAndNameWrap GetBarCodeAndNameWrapByBarCodeAndName(BarCodeAndName barCodeAndName)
        {
            foreach (var wrap in _wrapList)
            {
                if (wrap.BarCodeAndNameObject == barCodeAndName)
                    return wrap;
            }
            return null;
        }

        private BomEntrySingleModel GetNotUseBomEntrySingleModelByMaterialItemId(int materialItemId)
        {
            foreach (var bomEntrySingleModel in _bomEntrySingleModels)
            {
                if (bomEntrySingleModel.FBarCodeAndNameWrap == null
                    && bomEntrySingleModel.FBomEntryModel.MaterialItemId == materialItemId)
                {
                    return bomEntrySingleModel;
                }
            }
            return null;
        }

        private void BarCodeAndNameObject_BarCodeInputEnd(BarCodeAndName barCodeAndName, lmbcprintlogModel printlogModel)
        {
            try
            {
                //查物料表，看是否物料在系统中
                var iCItemModel = _staticDataQuerier.GetVIcItemQueryModel(printlogModel.Fitemid);
                if (iCItemModel == null)
                {
                    MsgBox.ShowError(String.Format("产品/物料不在系统中：{0}", printlogModel.Fitemid));
                    return;
                }

                var bomEntrySingleModel = GetNotUseBomEntrySingleModelByMaterialItemId(printlogModel.Fitemid);
                if (bomEntrySingleModel == null)
                {
                    barCodeAndName.BarCode = "";
                    barCodeAndName.Focus();
                    return;
                }
                bomEntrySingleModel.IsAddToTheControl = true;
                var barCodeAndNameWrap = GetBarCodeAndNameWrapByBarCodeAndName(barCodeAndName);
                bomEntrySingleModel.FBarCodeAndNameWrap = barCodeAndNameWrap;

                barCodeAndName.FlmbcprintlogModel = printlogModel;
                barCodeAndName.FName = bomEntrySingleModel.FBomEntryModel.MaterialItemName;
                barCodeAndName.FProductDetailModel = new TProductDetailModel();
                barCodeAndName.FProductDetailModel.ProcedureNo = lookUpEditProcedureNo.Text.Trim();
                barCodeAndName.FProductDetailModel.ProcedureName = textEditProcedureName.Text.Trim();
                barCodeAndName.FProductDetailModel.Idx = barCodeAndName.Index;
                barCodeAndName.FProductDetailModel.RowGuid = Guid.NewGuid().ToString("N");
                barCodeAndName.FProductDetailModel.ChildItemBarCode = barCodeAndName.BarCode;
                barCodeAndName.FProductDetailModel.ChildItemId = printlogModel.Fitemid;
                barCodeAndName.FProductDetailModel.ChildItemName = iCItemModel.FName;
                barCodeAndName.FProductDetailModel.ChildItemNumber = iCItemModel.FNumber;
                barCodeAndName.FProductDetailModel.UseStatus = 1;
                barCodeAndName.FProductDetailModel.InputId = UserSession.CurrentUser.UserId;
                barCodeAndName.FProductDetailModel.ExtChar4 = UserSession.CurrentUser.UserName;
                barCodeAndName.FProductDetailModel.InputDate = DateTime.Now;

                if (barCodeAndNameWrap.NextBarCodeAndNameWrapObject != null)
                {
                    barCodeAndNameWrap.NextBarCodeAndNameWrapObject.BarCodeAndNameObject.Focus();
                }

                if (barCodeAndName.IsTheLastControl)
                {
                    SaveProductHeaderAndDetail();
                }
            }
            catch (Exception exception)
            {
                MsgBox.ShowError(exception.Message);
            }
        }

        /// <summary>
        ///   设置焦点，index从0开始
        /// </summary>
        /// <param name = "index"></param>
        private void SetFocus(int index)
        {
            if (_wrapList.Count > index)
            {
                _wrapList[index].BarCodeAndNameObject.Focus();
            }
        }

        public void SaveProductHeaderAndDetail()
        {
            try
            {
                if (!_parentProductBaseEdit.AddSuccess)
                {
                    _parentProductBaseEdit.Save();
                }
                //主键
                barCodeAndNameParent.FProductHeaderModel.ProductBaseRowGuid =
                    _parentProductBaseEdit.ProductBaseModel.RowGuid;
                //订单号码
                barCodeAndNameParent.FProductHeaderModel.ExtChar1 = textEditOrderId.Text;
                foreach (var barCodeAndNameWrap in _wrapList)
                {
                    barCodeAndNameWrap.BarCodeAndNameObject.FProductDetailModel.ParentProductItemBarCode =
                        barCodeAndNameParent.FProductHeaderModel.ProductItemBarCode;
                }

                var headerModels = new List<TProductHeaderModel>();
                var detailModels = new List<TProductDetailModel>();
                headerModels.Add(barCodeAndNameParent.FProductHeaderModel);
                foreach (var barCodeAndNameWrap in _wrapList)
                {
                    detailModels.Add(barCodeAndNameWrap.BarCodeAndNameObject.FProductDetailModel);
                }
                _productPersist.SaveProductHeaderAndDetailModels(headerModels, detailModels);
                var procudtDetailViewControl = _parentProductBaseEdit.ProcudtDetailViewControl;
                if (procudtDetailViewControl != null)
                {
                    procudtDetailViewControl.AppendProductDetailModels(detailModels);
                }
                InitializeInputProduct();
            }
            catch (Exception exception)
            {
                MsgBox.ShowError(exception.Message);
            }
        }

        private void TextEditOrderIdKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char) Keys.Enter)
            {
                //this.barCodeAndNameParent.Focus();
                lookUpEditProcedureNo.Focus();
            }
        }
    }
}